import 'dart:convert';
import 'dart:typed_data';

class ByteUtil {
  ByteUtil._(); // 私有构造函数，防止实例化

  /// 将字节数组转换为字符串，默认带空格
  static String byteArrayToString(List<int> bytes, {bool withEmpty = true}) {
    return bytes.map((byte) => byte.toRadixString(16).padLeft(2, '0')).join(withEmpty ? ' ' : '');
  }

  /// 带空格的16进制字符串，转字节数组，比如 "47 54 82 04 00 03 01 d8 ff"
  static List<int> hexStringToBytes(String hexString) {
    return hexString
        .split(' ')
        .map((hex) => int.parse(hex, radix: 16))
        .toList();
  }

  /// 16进制转带符号数字（2字节）
  static int toSignedInt2(int hex) {
    if (hex >= 0x8000) {
      hex = hex ^ 0xFFFF;
      hex = hex + 1;
      return -hex;
    } else {
      return hex;
    }
  }

  /// 16进制转带符号数字（1字节）
  static int toSignedInt1(int hex) {
    if (hex >= 0x80) {
      hex = hex ^ 0xFF;
      hex = hex + 1;
      return -hex;
    } else {
      return hex;
    }
  }

  /// 将字节转换为十进制字符串
  static String byteToDecimalString(int b) {
    return int.parse(byteToHexString(b), radix: 16).toString();
  }

  /// 将十进制字符串转换为字节
  static int decStringToByte(String decimalStr) {
    int value = int.parse(decimalStr);
    return value & 0xff;
  }

  /// 将字节转换为十六进制字符串
  static String byteToHexString(int b) {
    String hex = b.toRadixString(16).padLeft(2, '0');
    return hex;
  }

  /// 将字节数组转换为整数
  static int byteArrayToInt(List<int> bytes) {
    int res = 0;
    for (int i = 0; i < bytes.length; i++) {
      res += (bytes[i] & 0xff) << (i * 8);
    }
    return res;
  }

  /// 将整数转换为字节数组
  static List<int> intToBytes(int value) {
    return [
      value & 0xff,
      (value >> 8) & 0xff,
      (value >> 16) & 0xff,
      (value >> 24) & 0xff,
    ];
  }

  /// 将短整数转换为字节数组（2字节）
  static List<int> shortToByteArray(int s) {
    return [
      (s >> 8) & 0xff,
      s & 0xff,
    ];
  }

  /// 将字符串转换为字节数组，长度为strLen
  static List<int> stringToBytes(String str, int strLen) {
    if (strLen == 0) {
      return [];
    }
    List<int> bytes = utf8.encode(str);
    if (bytes.length < strLen) {
      return List<int>.from(bytes)..length = strLen;
    }
    return bytes.sublist(0, strLen);
  }

  /// 获取字节数组的子数组
  static List<int> getSubBytes(List<int> bytes, int start, int end) {
    if (start < 0 || end >= bytes.length || start > end) {
      return [];
    }
    return bytes.sublist(start, end + 1);
  }

  /// 获取非零字节数组
  static List<int> getBytesNonZero(List<int> bytes) {
    int count = bytes.length;
    for (int i = bytes.length - 1; i >= 0; i--) {
      if (bytes[i] != 0) {
        count = i + 1;
        break;
      }
    }
    return bytes.sublist(0, count);
  }

  /// 将字节数组转换为长整数
  static int bytesToLong(List<int> bytes) {
    ByteData byteData = ByteData.sublistView(Uint8List.fromList(bytes));
    return byteData.getInt64(0, Endian.little);
  }

  /// 将字节数组转换为短整数
  static int bytesToShort(List<int> bytes) {
    ByteData byteData = ByteData.sublistView(Uint8List.fromList(bytes));
    return byteData.getInt16(0, Endian.little);
  }

  /// 整数转二进制字符串，保证长度为 8 位，不足的左边补0，如 3 = 00000011
  static String intToBinaryString(int value) {
    return value.toRadixString(2).padLeft(8, '0');
  }

  /// 复制字节
  static void copyBytes(List<int>? lbytes, List<int>? rbytes, int lstart, int rstart) {
    if (lbytes != null && rbytes != null && lstart >= 0) {
      for (int i = lstart, j = rstart;
      j < rbytes.length && i < lbytes.length;
      i++, j++) {
        lbytes[i] = rbytes[j];
      }
    }
  }

  /// 代替Java 的 System.arrayCopy
  static void arrayCopy(List<dynamic> src, int srcPos, List<dynamic> dest, int destPos,
      int length) {
    // 检查边界条件
    if (srcPos < 0 ||
        destPos < 0 ||
        length < 0 ||
        srcPos + length > src.length ||
        destPos + length > dest.length) {
      return;
    }

    // 执行复制操作
    for (int i = 0; i < length; i++) {
      dest[destPos + i] = src[srcPos + i];
    }
  }

  /// 比较两个 List<int> 是否完全一致
  ///
  /// [list1] 和 [list2] 是要比较的列表。
  /// 返回 `true` 表示两个列表完全一致（长度相同且每个元素都相同），否则返回 `false`。
  bool isSameList(List<int> list1, List<int> list2) {
    // 如果长度不同，直接返回 false
    if (list1.length != list2.length) {
      return false;
    }

    // 比较每个元素是否相同
    for (int i = 0; i < list1.length; i++) {
      if (list1[i] != list2[i]) {
        return false;
      }
    }

    return true; // 完全一致
  }

  /// CRC XModem 校验
  static List<int> crcXModem(List<int> bytes) {
    // Prepare a result list with additional 2 bytes for CRC
    List<int> r = List<int>.filled(bytes.length + 2, 0);

    int crc = 0x00; // initial value
    int polynomial = 0x1021;

    for (int index = 0; index < bytes.length; index++) {
      int b = bytes[index];
      for (int i = 0; i < 8; i++) {
        bool bit = ((b >> (7 - i)) & 1) == 1;
        bool c15 = ((crc >> 15) & 1) == 1;
        crc <<= 1;
        if (c15 ^ bit) {
          crc ^= polynomial;
        }
      }
    }

    crc &= 0xffff; // Ensure CRC is 16-bit

    // Convert the CRC value into two bytes
    List<int> crcBytes = shortToByteArray(crc);

    // Copy original bytes to the result list
    for (int i = 0; i < bytes.length; i++) {
      r[i] = bytes[i];
    }

    // Append the CRC bytes to the result list
    r[bytes.length] = crcBytes[0];
    r[bytes.length + 1] = crcBytes[1];

    return r;
  }

}
